package BLC

import (
	"bytes"
	"crypto/sha256"
	"encoding/gob"
	"encoding/hex"
	"fmt"
	"log"
)

//实现区块中的交易
type Transaction struct {
	TxHash []byte
	VIns   []*TxInput
	VOuts  []*TxOutput
}

func (tx *Transaction) HashTransaction() {

	var result bytes.Buffer
	encode := gob.NewEncoder(&result)
	err := encode.Encode(tx)
	if err != nil {
		log.Panicf("tx hash transaction failed !", err)
	}
	hash := sha256.Sum256(result.Bytes())
	tx.TxHash = hash[:]
}

//生成coincide 交易
func NewCoinBaseTransaction(addr string) *Transaction {
	txInput := &TxInput{[]byte{}, -1, "genesis data"}
	txOutput := &TxOutput{10, addr}
	txCoinBase := &Transaction{nil, []*TxInput{txInput}, []*TxOutput{txOutput}}
	txCoinBase.HashTransaction()
	return txCoinBase
}

//生成转账交易
func NewSimpleTransaction(from, to string, amount int, chain *BlockChain, txs []*Transaction) *Transaction {

	var txInputs []*TxInput
	var txOutputs []*TxOutput

	//查找指定地址 可用UTXO
	money, spendableUTXO := chain.FindSpendableUTXO(from, int64(amount), txs)
	//查询余额
	for txHash, indexArray := range spendableUTXO {
		if len(indexArray) == 0 {
			fmt.Println("获取的未消费是空的")
			return nil
		}
		txHashByte, _ := hex.DecodeString(txHash)
		for _, index := range indexArray {
			txInput := &TxInput{txHashByte, index, from}
			txInputs = append(txInputs, txInput)
		}
	}

	//转账
	txOutput := &TxOutput{int64(amount), to}
	txOutputs = append(txOutputs, txOutput)

	//找零
	txOutput = &TxOutput{money - int64(amount), from}
	txOutputs = append(txOutputs, txOutput)

	//生成转账交易
	tx := &Transaction{[]byte{}, txInputs, txOutputs}
	tx.HashTransaction()

	return tx
}

//判断指定交易 是一个coinbase 交易
func (tx *Transaction) IsCoinBaseTransaction() bool {
	return len(tx.VIns[0].TxHash) == 0 && tx.VIns[0].VOut == -1
}
